Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMS_PERMISSION: optionally use raw id user lookups #1481

Merged
merged 9 commits into from Apr 15, 2013
Merged

CMS_PERMISSION: optionally use raw id user lookups #1481

merged 9 commits into from Apr 15, 2013

Conversation

jimr
Copy link

@jimr jimr commented Oct 17, 2012

The "view restrictions" and "page permissions" inlines on the "page"
admin change forms can cause performance problems where there are many
thousands of users being put into simple select boxes. Added a new
setting (CMS_RAW_ID_USERS) that, if set, forces the inlines on that page
to use standard Django admin "raw ID" lookups rather than select boxes.
The restriction on which users may be selected should still be honoured
by the new widget because we set the 'limit_choices_to' attribute to be
the same as the queryset on the original widget.

Using raw_id_fields in combination with limit_choices_to blows up if you
have many thousands of users. For this reason, we only apply this limit
if the number of users is relatively small (< 500, though that figure is
somewhat arbitrary). If the number of users we need to limit to is
greater than that, we use the usual input field instead unless the user
is a CMS superuser, in which case we bypass the limit. Unfortunately,
this means that non-superusers won't see any benefit from this change.

James Rutherford added 3 commits September 14, 2012 10:28
The "view restrictions" and "page permissions" inlines on the "page"
admin change forms can cause performance problems where there are many
thousands of users being put into simple select boxes. Added a new
setting (CMS_RAW_ID_USERS) that, if set, forces the inlines on that page
to use standard Django admin "raw ID" lookups rather than select boxes.
The restriction on which users may be selected should still be honoured
by the new widget because we set the 'limit_choices_to' attribute to be
the same as the queryset on the original widget.

Using raw_id_fields in combination with limit_choices_to blows up if you
have many thousands of users. For this reason, we only apply this limit
if the number of users is relatively small (< 500, though that figure is
somewhat arbitrary). If the number of users we need to limit to is
greater than that, we use the usual input field instead unless the user
is a CMS superuser, in which case we bypass the limit. Unfortunately,
this means that non-superusers won't see any benefit from this change.
@jimr
Copy link
Author

jimr commented Oct 17, 2012

As mentioned on the developers mailing list: https://groups.google.com/forum/#!topic/django-cms-developers/zprGZo6Pz1Y

@digi604
Copy link
Contributor

digi604 commented Oct 17, 2012

Ok this needs docs and it needs merge with develop. I don't think we gonna release an other 2.2 release for this.

@jimr
Copy link
Author

jimr commented Oct 18, 2012

OK, I'll add some docs & remove the version bump.

Also removed the previous version bump so it can merge cleanly upstream.
@digi604
Copy link
Contributor

digi604 commented Nov 12, 2012

Looks good to me... @ojii could you have a look as well?


limit_choices = True
use_raw_id = False
if hasattr(settings, 'CMS_RAW_ID_USERS') and settings.CMS_RAW_ID_USERS:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if getattr(settings, 'CMS_RAW_ID_USERS', False):

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be clearer.

@ojii
Copy link
Contributor

ojii commented Nov 12, 2012

I have a few isuses with the patch itself, but on top of that I'm (as we all know by now) not a huge fan of adding new settings.

If this is such a good thing, why don't we just make it the default?

@digi604
Copy link
Contributor

digi604 commented Nov 12, 2012

Good point @ojii. Remove the setting and make it an Raw ID field if there are more 500 users? Maybe even 200?

@jimr
Copy link
Author

jimr commented Nov 12, 2012

I only made it a setting because I didn't want to alter default behaviour. With thousands of user accounts, it's currently infeasible to use CMS_PERMISSION because of the issues addressed by this patch, so making it default would make sense to me.

@digi604
Copy link
Contributor

digi604 commented Mar 28, 2013

please remerge with develop and i think too that the configurable limit would be better...

@@ -26,6 +26,9 @@
# Whether to enable permissions.
CMS_PERMISSION = False

# Whether to use raw ID lookups for users when CMS_PERMISSION is set to True
CMS_RAW_ID_USERS = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with regards to the limit, how about making this setting either False (disable the raw ID lookup) or an integer which is the limit?

@jimr
Copy link
Author

jimr commented Apr 2, 2013

OK, sounds good. I'll bring my branch up to date & make the limit configurable.

@jimr
Copy link
Author

jimr commented Apr 5, 2013

@ojii should I put CMS_RAW_ID_USERS in DEFAULTS in cms/utils/conf.py as RAW_ID_USERS? Seems the arrangement of settings has changed rather a lot since I started.

@ojii
Copy link
Contributor

ojii commented Apr 5, 2013

yes please

James Rutherford added 3 commits April 5, 2013 14:14
Conflicts:
	cms/conf/global_settings.py
So the RAW_ID_USERS setting should now be either left as False or set to
a positive integer which will be the threshold for the number of users
above which the raw ID widget will be used.
@@ -27,6 +27,16 @@ class PagePermissionInlineAdmin(TabularInline):
exclude = ['can_view']
extra = 0 # edit page load time boost

def __getattribute__(self, name):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

github seems to have lost this discussion, but this works for me:

In [1]: class A:
   ...:     @property
   ...:     def b(self):
   ...:         return []
   ...:     

In [2]: a = A()

In [3]: isinstance(a.b, list)
Out[3]: True

In [4]: isinstance(a.b, (list, tuple))
Out[4]: True

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Django checks it on the class, not an instance, otherwise it would indeed work.

https://github.com/django/django/blob/master/django/contrib/admin/validation.py#L267

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class classproperty(object):

    def __init__(self, fget):
        self.fget = fget

    def __get__(self, owner_self, owner_cls):
        return self.fget(owner_cls)

## -- End pasted text --

In [2]: class A:
   ...:     @classproperty
   ...:     def b(cls):
   ...:         return []
   ...:     

In [3]: A.b
Out[3]: []

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so that would work, but do you think it's better than just using __getattribute__? Up to you, but IMO the original code is easier to understand.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arguably, but I just really am not a fan of __getattribute__. had too many issues with it in the past...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Let me know if this is blocking the merge and I'll change it, but my personal preference would be to leave as-is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

had a chat with @digi604 and @stefanfoulis and we all three prefer classproperty over __getattribute__.

I think the best place to put that helper class is probably cms.utils.helpers, so if you could change this bit to make use of that technique, that would be highly appreciated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okie doke.

Added the new classproperty helper in cms.utils.helpers.
digi604 added a commit that referenced this pull request Apr 15, 2013
CMS_PERMISSION: optionally use raw id user lookups
@digi604 digi604 merged commit bd166e3 into django-cms:develop Apr 15, 2013
@jimr
Copy link
Author

jimr commented Apr 15, 2013

Thanks!

@jimr jimr deleted the raw_id_users branch April 15, 2013 15:38
@digi604
Copy link
Contributor

digi604 commented Apr 15, 2013

Thank YOU!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants